package com.charlie.beans;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.PreRemove;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Вова
 */
@Entity
@Table(name = "SHIPMENT_ORDER")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "ShipmentOrder.findAll", query = "SELECT s FROM ShipmentOrder s"),
    @NamedQuery(name = "ShipmentOrder.findBySoId", query = "SELECT s FROM ShipmentOrder s WHERE s.soId = :soId"),
    @NamedQuery(name = "ShipmentOrder.findByCreationDate", query = "SELECT s FROM ShipmentOrder s WHERE s.creationDate = :creationDate"),
    @NamedQuery(name = "ShipmentOrder.findByDueDate", query = "SELECT s FROM ShipmentOrder s WHERE s.dueDate = :dueDate"),
    @NamedQuery(name = "ShipmentOrder.findByShipingCost", query = "SELECT s FROM ShipmentOrder s WHERE s.shipingCost = :shipingCost"),
    @NamedQuery(name = "ShipmentOrder.findByCost", query = "SELECT s FROM ShipmentOrder s WHERE s.cost = :cost"),
    @NamedQuery(name = "ShipmentOrder.findByEmail", query = "SELECT s FROM ShipmentOrder s WHERE s.email = :email"),
    @NamedQuery(name = "ShipmentOrder.findByLocation", query = "SELECT s FROM ShipmentOrder s WHERE s.location = :location"),
    @NamedQuery(name = "ShipmentOrder.findByIsSubscribed", query = "SELECT s FROM ShipmentOrder s WHERE s.isSubscribed = :isSubscribed")})
public class ShipmentOrder implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SHIPMENT_ORDER_SEQ")
    @SequenceGenerator(name = "SHIPMENT_ORDER_SEQ", sequenceName = "SHIPMENT_ORDER_SO_ID_SEQ", allocationSize = 1)
    @Column(name = "SO_ID")
    private Integer soId;
    @Basic(optional = false)
    @NotNull
    @Column(name = "CREATION_DATE")
    @Temporal(TemporalType.DATE)
    private Date creationDate;
    @Basic(optional = false)
    @NotNull
    @Column(name = "DUE_DATE")
    @Temporal(TemporalType.DATE)
    private Date dueDate;
    @Column(name = "SHIPING_COST")
    private Integer shipingCost;
    @Column(name = "COST")
    private Integer cost;
    @Basic(optional = true)
    @Size(min = 1, max = 254)
    @Column(name = "EMAIL")
    private String email;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 250)
    @Column(name = "LOCATION")
    private String location;
    @Column(name = "IS_SUBSCRIBED")
    private Short isSubscribed;
    @JoinColumn(name = "WAREHOUSE_ID", referencedColumnName = "WAREHOUSE_ID")
    @ManyToOne(optional = false)
    private Warehouse warehouseId;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "soId")
    private Collection<SoHistory> soHistoryCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "soId")
    private Collection<SoProduct> soProductCollection;

    public ShipmentOrder() {
    }

    public ShipmentOrder(Integer soId) {
        this.soId = soId;
    }

    public ShipmentOrder(Integer soId, Date creationDate, Date dueDate, String email, String location) {
        this.soId = soId;
        this.creationDate = creationDate;
        this.dueDate = dueDate;
        this.email = email;
        this.location = location;
    }

    @PreRemove
    public void remove() {
        this.soProductCollection.clear();
    }

    public Integer getSoId() {
        return soId;
    }

    public void setSoId(Integer soId) {
        this.soId = soId;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public Date getDueDate() {
        return dueDate;
    }

    public void setDueDate(Date dueDate) {
        this.dueDate = dueDate;
    }

    public Integer getShipingCost() {
        return shipingCost;
    }

    public void setShipingCost(Integer shipingCost) {
        this.shipingCost = shipingCost;
    }

    public Integer getCost() {
        return cost;
    }

    public void setCost(Integer cost) {
        this.cost = cost;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public Short getIsSubscribed() {
        return isSubscribed;
    }

    public void setIsSubscribed(Short isSubscribed) {
        this.isSubscribed = isSubscribed;
    }

    public Warehouse getWarehouseId() {
        return warehouseId;
    }

    public void setWarehouseId(Warehouse warehouseId) {
        this.warehouseId = warehouseId;
    }

    @XmlTransient
    public Collection<SoHistory> getSoHistoryCollection() {
        return soHistoryCollection;
    }

    public void setSoHistoryCollection(Collection<SoHistory> soHistoryCollection) {
        this.soHistoryCollection = soHistoryCollection;
    }

    @XmlTransient
    public Collection<SoProduct> getSoProductCollection() {
        return soProductCollection;
    }

    public void setSoProductCollection(Collection<SoProduct> soProductCollection) {
        this.soProductCollection = soProductCollection;
    }
    
    public SoProduct getSoProduct(int productId) {
        for (SoProduct item : soProductCollection) {
            if (item.getProductId().getProductId().intValue() == productId) {
                return item;
            }
        }
        return null;
    }

    public SoProduct getSoProduct(Product product) {
        return getSoProduct(product.getProductId().intValue());
    }

    public void addItem(SoProduct product) {
        if (product != null) {
            product.setSoId(this);
            soProductCollection.add(product);
        }
    }

    public void removeItem(Product product) {
        if (product != null) {
            SoProduct item = getSoProduct(product);
            if (item != null) {
                soProductCollection.remove(item);
            }
        }
    }

    public void removeItem(SoProduct item) {
        if (item != null) {
            removeItem(item.getProductId());
        }
    }

    public int getItemsAmount() {
        return soProductCollection.size();
    }

    public int getTotalCost() {
        int sum = 0;
        for (SoProduct prod : soProductCollection) {
            sum += prod.getProductId().getCost() * prod.getAmount();
        }
        return sum;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (soId != null ? soId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof ShipmentOrder)) {
            return false;
        }
        ShipmentOrder other = (ShipmentOrder) object;
        if ((this.soId == null && other.soId != null) || (this.soId != null && !this.soId.equals(other.soId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.charlie.beans.ShipmentOrder[ soId=" + soId + " ]";
    }
}
